package cn.lhx.taglib.toolkit;
import java.io.Serializable;
import java.util.AbstractMap;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;

public class TimeFunction {

    private final static String wtb_en[] = {"am", "pm", "monday", "tuesday",
        "wednesday", "thursday", "friday", "saturday", "sunday", "january",
        "february", "march", "april", "may", "june", "july", "august",
        "september", "october", "november", "december", "gmt", "ut", "utc",
        "est", "edt", "cst", "cdt", "mst", "mdt", "pst", "pdt"};
    private final static String wtb_cn[] = {"上午", "下午", "星期一", "星期二", "星期三",
        "星期四", "星期五", "星期六", "星期天", "一月", "二月", "三月", "四月", "五月", "六月",
        "七月", "八月", "九月", "十月", "十一月", "十二月", "gmt", "ut", "utc", "est",
        "edt", "cst", "cdt", "mst", "mdt", "pst", "pdt"};
    //缓存容量
    private final static int maxCapacity = 10;
    //profile缓存
    private final static Map<Date, Map<String, String>> proBuf = new HashMap<Date, Map<String, String>>(maxCapacity);

    private final static Map<String, String> init(Date date) {
        //查找缓存
        Date lastDate = date;
        for (Iterator it = proBuf.keySet().iterator(); it.hasNext();) {
            lastDate = (Date) it.next();
            if (lastDate.equals(date)) {
                return proBuf.get(lastDate);
            }
        }
        //缓存中没有找到，new 一个Map
        Map<String, String> profile = new HashMap<String, String>();
        //解析日期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);//月重0开始
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
        weekDay = (weekDay == Calendar.SUNDAY) ? 7 : (weekDay - 1);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int am_pm = calendar.get(Calendar.AM_PM);//0 AM 1 PM
        //年
        profile.put("%Yc", year + "年");
        profile.put("%Ye", year + "");
        profile.put("%Y", year + "");
        //月
        profile.put("%Mc", wtb_cn[month + 9]);
        profile.put("%Me", wtb_en[month + 9]);
        profile.put("%M", (month + 1) + "");
        //日
        profile.put("%D", day + "");
        String dayDix = "th";
        //day调整1st、2nd、3rd
        dayDix = (day % 10 == 1 ? "st" : (day % 10 == 2 ? "nd" : (day % 10 == 3 ? "rd" : dayDix)));
        profile.put("%De", day + dayDix);
        profile.put("%Dc", day + "日");
        //星期
        profile.put("%W", weekDay + "");
        profile.put("%We", wtb_en[weekDay + 1]);
        profile.put("%Wc", wtb_cn[weekDay + 1]);
        //时间
        int hour12 = hour > 12 ? hour - 12 : hour;//转换成12小时格式
        profile.put("%T12", (hour12) + ":" + minute);
        profile.put("%T24", hour + ":" + minute);
        //上下午
        profile.put("%N", wtb_en[am_pm]);
        profile.put("%Ne", wtb_en[am_pm]);
        profile.put("%Nc", wtb_cn[am_pm]);

        if (proBuf.size() < maxCapacity) {
            //放入缓存
            proBuf.put(date, profile);
        } else {
            //移除最旧的日期profile
            proBuf.remove(lastDate);
            proBuf.put(date, profile);
        }
//        System.out.println("proBuf.size= "+proBuf.size());
        return profile;
    }

    /**
     * 将日期转换成格式化字符串
     * @param str 带有给事标识符的字符串
     * @param date 日期对象
     *  @return
     * %Y[?]:年<br/>
     * %M[?]:月<br/>
     * %D[?]:日<br/>
     * %T[12|24]:时间，12表示十二小时制,24表示...
     * <br/>详细参数列表
     * <table border=1px>
     * 	<tr><td>格式符</td><td>形式,示例</td><td>格式符</td><td>形式,示例</td></tr>
     * <tr><td>%Y</td><td>数字,2010</td><td>%D</td><td>日,数字</td></tr>
     * <tr><td>%Yc</td><td>数字+年,2010年</td><td>%Dc</td><td>数字+日,23日</td></tr>
     * <tr><td>%Ye</td><td>数字,2009</td><td>%De</td><td>数字+th,23th</td></tr>
     * <tr><td>%M</td><td>数字,12</td><td>%W</td><td>星期，数字,7</td></tr>
     * <tr><td>%Mc</td><td>中文+月,十二月</td><td>%We</td><td>英文，sunday</td></tr>
     * <tr><td>%Me</td><td>英文,dec</td><td>%Wc</td><td>中文,星期天</td></tr>
     * <tr><td>%N</td><td>英文,am</td><td>%Ne</td><td>中文,星期天</td></tr>
     * <tr><td>%Nc</td><td>中文,上午</td><td>%T[12|24]</td><td>数字,12:30</td></tr>
     * </table>
     * Example:<br/>
     * str="今天是%Yc，%Mc,%Dc,%Wc"<br/>
     * 输出:今天是2010年，一月,13日,星期三<br/>
     * str=""今天是%Yc，%Me,%De,%We""<br/>
     * 输出:今天是2010年，january,13rd,wednesday<br/>
     */
    public static String getFormateTimeStr(String str, Date date) {
        //获得参数
        Map<String, String> profile = init(date);
        //正则解析
        java.util.regex.Pattern pattern = Pattern.compile("\\%[M,D,Y,T,N,W]([ce~]|[124]{0,2})");
        java.util.regex.Matcher matcher = pattern.matcher(str);
        boolean isFind = matcher.find();
        StringBuffer sb = new StringBuffer();
        while (isFind) {
            String findStr = matcher.group();
//			System.out.println("findStr =="+findStr);
//			System.out.println("group1== "+matcher.group(1)); 
//			System.out.println("StartIndex== "+matcher.start());
//			System.out.println("EndIndex== "+matcher.end());
            if (profile.get(findStr) != null) {
                //如果找到了就用profile里格式化串替换标记
                matcher.appendReplacement(sb, profile.get(findStr));
            }
            isFind = matcher.find();
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    public static void main(String[] args) {
        Date date = new Date();
        String a = new String();
        long a1 = System.currentTimeMillis();
        System.out.println("开始时间：" + date.toString());
        for (int i = 0; i < 100; i++) {
            date = new Date();
            a = TimeFunction.getFormateTimeStr("%Mc 你好啊%De,我再找 地方%Ye单位额 at %T12 %Nc 正文撒地方%We", date);
        }
        Date date2 = new Date();
        for (int i = 0; i < 100; i++) {
            a = TimeFunction.getFormateTimeStr("%Mc 你好啊%De,我再找 地方%Ye单位额 at %T12 %Nc 正文撒地方%We", date2);
        }
        for (int i = 0; i < 100; i++) {
            a = TimeFunction.getFormateTimeStr("%Mc 你好啊", date);
        }

        System.out.println(a);
        long a2 = System.currentTimeMillis();
        System.out.println("结束时间：" + (a2 - a1));
//		System.out.println(TimeFunction.getFormateTimeStr("今天是%Yc，%Mc,%Dc,%Wc", date));
//		System.out.println(TimeFunction.getFormateTimeStr("今天是%Yc，%Me,%De,%We", date));
    }

}
